package vpn

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"sync"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { return true },
}

type SignalingServer struct {
	clients map[string]*Client
	mutex   sync.RWMutex
}

func NewSignalingServer() *SignalingServer {
	return &SignalingServer{
		clients: make(map[string]*Client),
	}
}

func (s *SignalingServer) HandleWebSocket(c *gin.Context) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Printf("WebSocket upgrade error: %v", err)
		return
	}

	clientID := c.Query("client")
	if clientID == "" {
		conn.Close()
		return
	}

	client := &Client{
		Conn:   conn,
		Room:   c.Query("room"),
		UserId: clientID,
	}

	s.mutex.Lock()
	s.clients[clientID] = client
	s.mutex.Unlock()

	log.Printf("Client connected: %s", clientID)

	// 处理消息
	for {
		var msg Message
		_, str, err := conn.ReadMessage()
		if err != nil {
			log.Printf("Read error: %v", err)
			break
		}
		if string(str) == "ping" {
			conn.WriteMessage(websocket.TextMessage, []byte("pong"))
			continue
		}

		err = json.Unmarshal(str, &msg)
		if err != nil {
			log.Printf("Read JSON error: %v", err)
			break
		}

		switch msg.Type {
		case "status":
			err = s.handleStatusMessage(msg.Data)
			if err != nil {
				log.Printf("handleStatusMessage error: %v", err)
			}
		default:
			s.routeMessage(msg)
		}
	}

	s.mutex.Lock()
	delete(s.clients, clientID)
	s.mutex.Unlock()
	conn.Close()
}

// 同步客户端信息
func (s *SignalingServer) handleStatusMessage(msg any) error {
	jsonData, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	var client Client
	err = json.Unmarshal(jsonData, &client)
	if err != nil {
		return err
	}
	targetClient, exists := s.clients[client.UserId]
	if !exists {
		return errors.New("user_id not found")
	}

	targetClient.ControlFlag = client.ControlFlag
	targetClient.ControlBy = client.ControlBy
	targetClient.Room = client.Room
	if len(client.PreviewImg) > 0 {
		targetClient.PreviewImg = client.PreviewImg
	}
	if len(client.Screens) > 0 {
		targetClient.Screens = client.Screens
	}
	return nil
}

// 转发消息
func (s *SignalingServer) routeMessage(msg Message) {
	fmt.Printf("🔄 信令服务器转发: %s -> %s, 类型: %s\n", msg.From, msg.To, msg.Type)

	s.mutex.RLock()
	targetClient, exists := s.clients[msg.To]
	s.mutex.RUnlock()

	if exists {
		err := targetClient.Conn.WriteJSON(msg)
		if err != nil {
			log.Printf("❌ 转发消息失败: %v", err)
		} else {
			fmt.Printf("✅ 消息转发成功\n")
		}
	} else {
		fmt.Printf("❌ 目标客户端不存在: %s\n", msg.To)
	}
}

// 返回所有客户端信息
func (s *SignalingServer) Users(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"code": 0, "records": s.clients})
}
